import json
import os
import pandas as pd


class Graph:
    title_dictionary = {}

    speaker_dictionary = {}
    speaker_id = 0

    tags_dictionary = {}
    tags_id = 0

    related_dictionary = {}

    vertex_id = 0
    vertex_list = []

    edge_list = []

    # 创建唯一映射
    def create_dict(self, data):
        self.speaker_id = self.tags_id = 0

        # 创建title字典
        for i in range(len(data["title"])):
            temp_string = data["title"][i]
            temp_string = temp_string.lower()
            temp_string = temp_string.strip()
            # print("temp: ", temp_string)
            self.title_dictionary[temp_string] = i

        # 创建speaker字典
        for i in range(len(data["main_speaker"])):
            temp_string = data["main_speaker"][i]
            if temp_string not in self.speaker_dictionary:
                self.speaker_dictionary[temp_string] = self.speaker_id
                self.speaker_id = self.speaker_id + 1

        # 创建tags字典
        for i in range(len(data["tags_split"])):
            for j in data["tags_split"][i]:
                if j not in self.tags_dictionary:
                    self.tags_dictionary[j] = self.tags_id
                    self.tags_id = self.tags_id + 1

        # 创建related字典
        for i in range(len(data["related_talks"])):
            json_info_list = get_json_list(data["related_talks"][i])
            json_info = []
            for j in json_info_list:
                json_info.append(json.loads(j))
            related_talks = []
            for j in json_info:
                related_talks.append(j["title"])
            self.related_dictionary[i] = related_talks

    def create_vertex(self):
        # 创建点
        self.vertex_id = 0

        # 遍历title列表
        for i in self.title_dictionary.items():
            temp_dict = {"id": self.vertex_id,
                         "label": "talks",
                         "value": i[0]}
            self.title_dictionary[i[0]] = self.vertex_id
            self.vertex_id = self.vertex_id + 1
            self.vertex_list.append(temp_dict)

        # 遍历speaker列表
        for i in self.speaker_dictionary.items():
            temp_dict = {"id": self.vertex_id,
                         "label": "speakers",
                         "value": i[0]}
            self.speaker_dictionary[i[0]] = self.vertex_id
            self.vertex_id = self.vertex_id + 1
            self.vertex_list.append(temp_dict)

        # 遍历tags列表
        current_label = "tags"
        for i in self.tags_dictionary.items():
            temp_dict = {"id": self.vertex_id,
                         "label": current_label,
                         "value": i[0]}
            self.tags_dictionary[i[0]] = self.vertex_id
            self.vertex_id = self.vertex_id + 1
            self.vertex_list.append(temp_dict)

    def create_edges(self, data):
        # 创建边
        # 创建related_talks边
        for i in self.related_dictionary.items():
            # print("i:", i)
            for j in i[1]:
                temp_string = j
                if j not in self.title_dictionary:
                    temp_string = j.replace("'", '"')
                # print("j:", j)

                # print(self.title_dictionary)
                temp_dict = {"from": i[0],
                             "to": self.title_dictionary[temp_string],
                             "label": "related_talks"}
                self.edge_list.append(temp_dict)

        # 创建speaker-talks边
        for i in range(len(data["main_speaker"])):
            temp_dict = {"from": self.speaker_dictionary[data["main_speaker"][i]],
                         "to": self.title_dictionary[data["title"][i]],
                         "label": "main_speaker"}
            self.edge_list.append(temp_dict)

        # 创建tags-talks边
        for i in range(len(data["tags_split"])):
            for j in data["tags_split"][i]:
                temp_dict = {
                    "from": self.title_dictionary[data["title"][i]],
                    "to": self.tags_dictionary[j],
                    "label": "tags"
                }
                self.edge_list.append(temp_dict)

    def make_graph(self, data):
        self.create_dict(data)
        self.create_vertex()
        self.create_edges(data)


def get_json_list(s):
    flag = 0
    json_list = []
    temp_string = ""
    s = s.replace('""', "'")
    s = s.replace('"', "'")
    s = s.replace('\\', "")
    s = s.replace("':", '":')
    s = s.replace("{'", '{"')
    s = s.replace(", '", ', "')
    s = s.replace(": '", ': "')
    s = s.replace("',", '",')
    for i in range(len(s)):
        if flag == 0 and s[i] != '{':
            continue
        temp_string = temp_string + s[i]
        if s[i] == '{':
            flag = flag + 1
        if s[i] == '}':
            flag = flag - 1
            if flag == 0:
                temp_string = temp_string.lower()
                temp_string = temp_string.strip()
                json_list.append(temp_string)
                temp_string = ""
                continue
    # print("json_list=")
    # for i in json_list:
    #     print(i)
    return json_list


def graph_to_files(graph):
    path = os.path.abspath('..') + os.sep + 'data' + os.sep
    f_vertex = open(path + "vertex", 'w')
    f_edge = open(path + "edge", 'w')
    for i in graph.vertex_list:
        f_vertex.write(str(i['id']) + ' "' + i["label"] + '" "' + i["value"] + '"' + os.linesep)

    for i in graph.edge_list:
        f_edge.write(str(i['from']) + " " + str(i["to"]) + ' "' + i["label"] + '"' + os.linesep)


def graph_to_grami_data(graph):
    path = os.path.abspath('..') + os.sep + 'data' + os.sep
    f_grami = open(path + "data.lg", 'w')
    f_v_label = open(path + "v_label", 'w')
    f_e_label = open(path + "e_label", 'w')
    f_grami.write("# t 1" + os.linesep)

    v_label_dict = {}
    v_label_index = 1
    id_label_dict = {}
    for i in graph.vertex_list:
        if i["label"] == "talks" \
                or i["label"] == "speakers":
            # or i["label"] == "tags"\
            if i["label"] not in v_label_dict:
                v_label_dict[i["label"]] = v_label_index
                f_v_label.write(str(v_label_index) + " " + i["label"] + os.linesep)
                id_label_dict[i["id"]] = i["label"]
                v_label_index = v_label_index + 1
            f_grami.write("v " + str(i["id"]) + " " + str(v_label_dict[i["label"]]) + os.linesep)
            continue

        if i["value"] not in v_label_dict:
            v_label_dict[i["value"]] = v_label_index
            f_v_label.write(str(v_label_index) + " " + i["value"] + os.linesep)
            id_label_dict[i["id"]] = i["value"]
            v_label_index = v_label_index + 1
        f_grami.write("v " + str(i["id"]) + " " + str(v_label_dict[i["value"]]) + os.linesep)

    e_label_dict = {}
    e_label_index = 1
    for i in graph.edge_list:
        if i["label"] == "related_talks":
            if i["label"] not in e_label_dict:
                e_label_dict[i["label"]] = e_label_index
                f_e_label.write(str(e_label_index) + " " + i["label"] + os.linesep)
                e_label_index = e_label_index + 1
            # f_grami.write("e " + str(i["from"]) + " " + str(i["to"]) + " " + str(e_label_dict[i["label"]]) + os.linesep)
            continue

        if i["label"] == "main_speaker":
            if i["label"] not in e_label_dict:
                e_label_dict[i["label"]] = e_label_index
                f_e_label.write(str(e_label_index) + " " + i["label"] + os.linesep)
                e_label_index = e_label_index + 1
            # if e_label_dict[i["label"]] != 1:
            f_grami.write("e " + str(i["from"]) + " " + str(i["to"]) + " " + str(e_label_dict[i["label"]]) + os.linesep)
            continue

        # if i["label"] not in e_label_dict:
        #     e_label_dict[i["label"]] = e_label_index
        #     f_e_label.write(str(e_label_index) + " " + i["label"] + os.linesep)
        #     e_label_index = e_label_index + 1
        #     # if e_label_dict[i["label"]] != 1:
        # f_grami.write("e " + str(i["from"]) + " " + str(i["to"]) + " " + str(e_label_dict[i["label"]]) + os.linesep)
        # continue

        f_grami.write(
            "e " + str(i["from"]) + " " + str(i["to"]) + " " + str(v_label_dict[id_label_dict[i["to"]]]) + os.linesep)


def graph_to_grami_data_tags(graph):
    path = os.path.abspath('..') + os.sep + 'data' + os.sep
    f_grami = open(path + "data.lg", 'w')
    f_v_label = open(path + "v_label", 'w')
    f_e_label = open(path + "e_label", 'w')
    f_grami.write("# t 1" + os.linesep)

    v_label_dict = {}
    v_label_index = 1
    id_label_dict = {}
    for i in graph.vertex_list:
        if i["label"] == "talks" \
                or i["label"] == "speakers":
            if i["label"] not in v_label_dict:
                v_label_dict[i["label"]] = v_label_index
                f_v_label.write(str(v_label_index) + " " + i["label"] + os.linesep)
                id_label_dict[i["id"]] = i["label"]
                v_label_index = v_label_index + 1
            f_grami.write("v " + str(i["id"]) + " " + str(v_label_dict[i["label"]]) + os.linesep)
            continue

        if i["value"] not in v_label_dict:
            v_label_dict[i["value"]] = v_label_index
            f_v_label.write(str(v_label_index) + " " + i["value"] + os.linesep)
            id_label_dict[i["id"]] = i["value"]
            v_label_index = v_label_index + 1
        f_grami.write("v " + str(i["id"]) + " " + str(v_label_dict[i["value"]]) + os.linesep)

    e_label_dict = {}
    e_label_index = 1
    for i in graph.edge_list:
        if i["label"] == "related_talks":
            if i["label"] not in e_label_dict:
                e_label_dict[i["label"]] = e_label_index
                f_e_label.write(str(e_label_index) + " " + i["label"] + os.linesep)
                e_label_index = e_label_index + 1
            # f_grami.write("e " + str(i["from"]) + " " + str(i["to"]) + " " + str(e_label_dict[i["label"]]) + os.linesep)
            continue

        if i["label"] == "main_speaker":
            if i["label"] not in e_label_dict:
                e_label_dict[i["label"]] = e_label_index
                f_e_label.write(str(e_label_index) + " " + i["label"] + os.linesep)
                e_label_index = e_label_index + 1
            # if e_label_dict[i["label"]] != 1:
            f_grami.write("e " + str(i["from"]) + " " + str(i["to"]) + " " + str(e_label_dict[i["label"]]) + os.linesep)
            continue

        # if i["label"] not in e_label_dict:
        #     e_label_dict[i["label"]] = e_label_index
        #     f_e_label.write(str(e_label_index) + " " + i["label"] + os.linesep)
        #     e_label_index = e_label_index + 1
        #     # if e_label_dict[i["label"]] != 1:
        # f_grami.write("e " + str(i["from"]) + " " + str(i["to"]) + " " + str(e_label_dict[i["label"]]) + os.linesep)
        # continue

        f_grami.write("e " + str(i["from"]) +
                      " " + str(i["to"]) +
                      " " + str(v_label_dict[id_label_dict[i["to"]]]) + os.linesep)


def graph_to_csv(graph):
    data = pd.DataFrame()
    name_list = []
    label_list = []
    for i in graph.vertex_list:
        name_list.append(i["value"])
        label_list.append(i["label"])
    data["name"] = name_list
    data["label"] = label_list
    data.to_csv("v")

    data = pd.DataFrame()
    from_list = []
    to_list = []
    e_label_list = []
    for i in graph.edge_list:
        from_list.append(graph.vertex_list[i["from"]]["value"])
        to_list.append(graph.vertex_list[i["to"]]["value"])
        e_label_list.append(i["label"])
    data["from"] = from_list
    data["to"] = to_list
    data["label"] = e_label_list
    data.to_csv("e")